<template>
  <div class="element" @click.stop="$emit('click',element,$event)" @contextmenu.stop.prevent="handlerRightClick" :style="transformStyleObj">
    <Transform v-if="showTransformHandler&&!wrapperTransform" v-model="newElement.transform" @change="handlerTransformChange"></Transform>
    <div :style="stylesObj" class="element-content">
      <element-chart ref="element" v-if="element.type==='chart'" :element="element"></element-chart>
      <element-text ref="element" v-else-if="element.type==='text'" :element="element"></element-text>
      <element-rich-text ref="element" v-else-if="element.type==='richText'" :element="element"></element-rich-text>
      <element-img ref="element" v-else-if="element.type==='img'" :element="element"></element-img>
      <element-template ref="element" v-else-if="element.type==='template'" :element="element"></element-template>
      <element-form ref="element" v-else-if="element.type==='form'" :element="element"></element-form>
      <element-svg ref="element" v-else-if="element.type==='svg'" :element="element"></element-svg>
    </div>
  </div>
</template>
<script>
import {Vue, Component, Prop,Watch} from 'vue-property-decorator'
import {throttle} from 'lodash'
import {
  State,
  Action,
  Getter
} from 'vuex-class'
import Transform from "./Transform.vue"

import {
  ElementImg,
  ElementText,
  ElementRichText,
  ElementChart,
  ElementTemplate,
  ElementForm,
  ElementSvg
} from "./elements"
@Component({
  components: {
    ElementImg,
    ElementText,
    ElementRichText,
    ElementChart,
    ElementTemplate,
    ElementForm,
    ElementSvg,
    Transform
  }
})
export default class Element extends Vue {
  @Prop(Object) wrapperTransform!:any
  @Prop(Object) element!:any
  @Action actChangeElement
  @State curElementId
  @State selectedElementsTransform
  $refs:{
    element:any
  }
  newElement={...this.element}

  get showTransformHandler(){
    return this.element.id===this.curElementId
  }

  get stylesObj () {
    return {
      borderWidth: this.element.border.size + "px",
      borderRadius: this.element.border.radius + "px",
      borderStyle: this.element.border.style,
      borderColor: this.element.border.color,
      display:this.element.show?"block":"none",
      animation:this.animation
    }
  }

  get transformStyleObj () {
    if(this.wrapperTransform){
      return {
        width: this.newElement.transform.width + "px",
        height: this.newElement.transform.height + "px",
        left: this.newElement.transform.left-this.wrapperTransform.left + "px",
        top: this.newElement.transform.top-this.wrapperTransform.top + "px",
        transform: "rotate("+ this.newElement.transform.rotate +"deg)",
      }

    }
    return {
      width: this.newElement.transform.width + "px",
      height: this.newElement.transform.height + "px",
      left: this.newElement.transform.left + "px",
      top: this.newElement.transform.top + "px",
      transform: "rotate("+ this.newElement.transform.rotate +"deg)",
    }
  }

  get animation () {
    let delay = 0
    const animations = this.element.animation.map(item => {
      let style = `${item.name} ${item.time}s ${item.function} ${item.delay + delay}s ${item.count}`
      delay = delay + item.delay + item.time * item.count
      return style
    })
    return animations.join(',')
  }

  @Watch('element')
  onElementChanged (newValue,oldValue): void {
    this.newElement = {...this.element}
    if(oldValue.event.test!=newValue.event.test){
      this.handlerEvent()
    }
  }


  handlerElementChange:any=function () {}
  _handlerElementChange(){
    this.actChangeElement({...this.newElement})
  }

  handlerTransformChange(): void{
    this.handlerElementChange({})
  }

  restartAnimation () {
    let old = [...this.newElement.animation]
    this.newElement.animation = []
    Promise.resolve(() => {
      this.newElement.animation = old
    })
  }

  handlerEvent(){
    if(this.newElement.event.test>0){
      try{
        if(this.newElement.event.type==='custom'){
          new Function("$dom","$data",this.newElement.event.custom)(this.$refs.element.$el,this.newElement.data)
        }
      }catch(e){
        console.error(e)
      }
    }
  }

  mounted() {
    this.newElement = {...this.element}
    this.handlerElementChange=throttle(this._handlerElementChange, 150, {leading: false})
  }
  handlerRightClick(e) {
    this.$emit("contextmenu", e, this.element);
  }
}
</script>
<style lang="less" scoped>
.element-content{
  height:100%;
  width:100%;
}
.element{
  position: absolute;
  left:0;
  top:0;
  word-break: break-all;
}
</style>
